

;;;;;
(defonce session-factory
  (delay (-> (Configuration.)
           .configure
           .buildSessionFactory)))

(defn add-authors
  [& authors]
  (with-open [session (.openSession @session-factory)]
    (let [tx (.beginTransaction session)]
      (doseq [author authors]
        (.save session author))
      (.commit tx))))

(add-authors (Author. "Christophe" "Grand") (Author. "Brian" "Carper")
  (Author. "Chas" "Emerick"))

(defn get-authors
  []
  (with-open [session (.openSession @session-factory)]
    (-> session
      (.createQuery "from Author")
      .list)))

(for [{:keys [firstName lastName]} (map bean (get-authors))]
  (str lastName ", " firstName))
;= ("Carper, Brian" "Emerick, Chas" "Grand, Christophe")

(defmacro with-session
  [session-factory & body]
  `(with-open [~'session (.openSession ~(vary-meta session-factory assoc
                                          :tag 'SessionFactory))]
     ~@body))

(defn get-authors
  []
  (with-session @session-factory
    (-> session
      (.createQuery "from Author")
      .list)))

(defmacro with-transaction
  [& body]
  `(let [~'tx (.beginTransaction ~'session)]
     ~@body
     (.commit ~'tx)))

(defn add-authors
  [& authors]
  (with-session @session-factory
    (with-transaction
      (doseq [author authors]
        (.save session author)))))